/*
Copyright (C) 2009-2010 Xanadu Development Team

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2
of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#include "../../tools/PacketReader.h"
#include "PlayerHandler.h"
#include "../../tools/PacketCreator.h"
#include "../../server/Player.h"
#include "../world/GuildMembers.h"
#include "../world/Guilds.h"
#include "../world/Guild.h"
#include "../../server/Map.h"
#include "../../tools/MySQLM.h"
#include "../world/World.h"
string valstr(int id);

void PlayerHandler::handleGuild(PacketReader& packet) {
	char type = packet.read();
	Guilds* guilds = player->getWorld()->getGuilds();
	switch(type) {
		case 0x00: // Unknown
			break;
		case 0x02: { // Create a guild
			if (player->getGuild() != 0 || player->getMap()->getID() != 200000301)
				return;
			string name = packet.readString();
			if (name.length() < 3 || name.length() > 12 || MySQL::getInstance()->isString("guilds", "guildname", name))
				return;
			guilds->create(player, name);
			break;
		}
		case 0x05:  { // Invite a player
			string name = packet.readString();
			if (player->getGuild() == 0 || player->getName() == name || player->getGuildRank() > 2) {
				return;
			}
			guilds->invite(player, name);
			break;
		}
		case 0x06: { // Join a guild
			int gid = packet.readInt();
			int cid = packet.readInt();
			if (player->getGuildInvite() != gid || player->getGuild() != 0 || cid != player->getID()) {
				player->setGuildInvite(0);
				return;
			}
			player->setGuildInvite(0);
			guilds->join(player, gid);
			break;
		}
		case 0x07: { // Leave a guild
			int playerid = packet.readInt();
			string name = packet.readString();
			if (player->getGuild() == 0 || player->getID() != playerid || player->getName() != name) {
				return;
			}
			guilds->leave(player);
			break;
		}
		case 0x08: { // Expell a player
			int playerid = packet.readInt();
			string name = packet.readString();
			if (player->getGuild() == 0 || player->getGuildRank() > 2 || player->getID() == playerid)
				return;
			guilds->expel(player, playerid, name);
			break;
		}
		case 0x10: { // Change the notice
			if (player->getGuild() == 0 || player->getGuildRank() > 2) {
				return;
			}
			string notice = packet.readString();
			Guild* guild = player->getGuild();
			guild->setNotice(notice);
			guild->getMembers()->send(PacketCreator().updateGuildNotice(guild->getID(), notice));
			mysqlpp::Connection::thread_start();
			mysqlpp::Connection* conn = MySQL::getInstance()->getPool()->grab();
			mysqlpp::Query query = conn->query("update guilds set notice='" + notice + "' where guildid=" + valstr(guild->getID()));
			query.execute();
			MySQL::getInstance()->getPool()->release(conn);
			mysqlpp::Connection::thread_end();
			break;
		}
		case 0x0a: { // Add or remove guildpoints
			if (player->getGuild() == 0) {
				return;
			}
			Guild* guild = player->getGuild();
			guild->setGuildPoints(guild->getGuildPoints() + packet.readInt());
			guild->getMembers()->send(PacketCreator().addGuildPoint(guild));
			break;
		}
		case 0x0d: { // Change the title's
			if (player->getGuild() == 0 || player->getGuildRank() != 1) {
				return;
			}
			string rank1 = packet.readString();
			string rank2 = packet.readString();
			string rank3 = packet.readString();
			string rank4 = packet.readString();
			string rank5 = packet.readString();
			Guild* guild = player->getGuild();
			guild->setRank(rank1, 0);
			guild->setRank(rank2, 1);
			guild->setRank(rank3, 2);
			guild->setRank(rank4, 3);
			guild->setRank(rank5, 4);
			guild->getMembers()->send(PacketCreator().updateGuildRanks(guild->getID(), rank1, rank2, rank3, rank4, rank5));
			mysqlpp::Connection::thread_start();
			mysqlpp::Connection* conn = MySQL::getInstance()->getPool()->grab();
			mysqlpp::Query query = conn->query();
			query << "update guilds set rank1=" << mysqlpp::quote << rank1 << ", rank2=" << mysqlpp::quote << rank2 << ", rank3=" << mysqlpp::quote << rank3 << ", rank4=" << mysqlpp::quote << rank4 << ", rank5=" << mysqlpp::quote << rank5 << " where guildid=" << valstr(guild->getID());
			query.execute();
			MySQL::getInstance()->getPool()->release(conn);
			mysqlpp::Connection::thread_end();
			break;
		}
		case 0x0e: { // Change someones rank
			int playerid = packet.readInt();
			char newRank = packet.read();
			if (player->getGuild() == 0 || player->getID() == playerid || player->getGuildRank() > 2 || (newRank <= 2 && player->getGuildRank() != 1) || newRank <= 1 || newRank > 5) {
				return;
			}
			guilds->changeRank(player, newRank, playerid);
			break;
		}
		case 0x0f: { // Change emblem
			if (player->getGuild() == 0 || player->getGuildRank() != 1 || player->getMap()->getID() != 200000301) {
				return;
			}
			Guild* guild = player->getGuild();
			guild->setLogoBG(packet.readShort());
			guild->setLogoBGColor(packet.read());
			guild->setLogo(packet.readShort());
			guild->setLogoColor(packet.read());
			guild->getMembers()->send(PacketCreator().showGuildEmblem(guild));
			mysqlpp::Connection::thread_start();
			mysqlpp::Connection* conn = MySQL::getInstance()->getPool()->grab();
			mysqlpp::Query query = conn->query("update guilds set logo=" + valstr(guild->getLogo()) + ", logocolor=" + valstr(guild->getLogoColor()) + ", logobg=" + valstr(guild->getLogoBG()) + ", logobgcolor=" + valstr(guild->getLogoBGColor()) + " where guildid=" + valstr(guild->getID()));
			query.execute();
			MySQL::getInstance()->getPool()->release(conn);
			mysqlpp::Connection::thread_end();
			break;
		}
		default:
			cout << "Unhandled guild type: 0x" << hex << (short) type << endl;
			break;
	}
}

void PlayerHandler::handleGuildDenie(PacketReader &packet) {
	packet.read();
	Player *from = player->getWorld()->getPlayerByName(packet.readString());
	if (from != 0) {
		from->send(PacketCreator().denieGuildInvite(player->getName()));
	}
	player->setGuildInvite(0);
}